package com.tianjishuju.cimiss.station.station.api;


import com.tianjishuju.cimiss.station.station.manager.DownFileRead;
import com.tianjishuju.cimiss.station.station.manager.FTPListAllFiles;
import com.tianjishuju.cimiss.station.station.model.*;
import com.tianjishuju.cimiss.station.station.util.ConvertUtil;
import com.tianjishuju.cimiss.station.station.util.HttpUtil;
import com.tianjishuju.cimiss.station.station.util.SignatureUtils;
import org.apache.commons.httpclient.Header;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.apache.poi.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.json.GsonJsonParser;
import org.springframework.web.bind.annotation.*;

import java.io.File;
import java.io.FileWriter;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@RestController
@RequestMapping("/test")
public class TestDataRes {
    private static Logger logger = Logger.getLogger(TestDataRes.class);

    @Value("${cimissUrl}")
    private String cimissUrl;//="http://10.230.89.55/cimiss-web/api?userId=BECQ_XXZX_show&pwd=yxjkk";

    @Value("${find.new.file.showurl}")
    private String showurl;//= "http://120.26.52.224/download";

    @Value("${find.host.vmhosts}")
    private String hosts;//= "http://10.230.126.249:8080";

    @Value("${AccessKeyId}")
    private String AccessKeyId;//= "c5c7dc0522efb328045e187c360a61b8";

    @Value("${AccessKeySecret}")
    private String AccessKeySecret;//= "2a860b8a0f57419f";

    @Value("${find.host.OceanStor9000}")
    private String OceanStor9000;//= "https://10.230.123.101:8088";

    @Value("${localDirectory:download}")
    private String localDirectory;//= "download";

    @Value("${FTPhost}")
    private String FTPhost;
    @Value("${FTPport}")
    private int FTPport;
    @Value("${FTPusername}")
    private String FTPusername;
    @Value("${FTPpassword}")
    private String FTPpassword;
    @Value("${FTPpath}")
    private String FTPpath;
    @Value("${user_email}")
    private String user_email;
    @Value("${user_password}")
    private String user_password;
    @Value("${modelid.shujuziyuan}")
    private String shujuziyuan;
    @Value("${ffAdress}")
    private String ffAdress;
    @Value("${getMeteoindexLife}")
    private String getMeteoindexLife;
    @Value("${getMeteoindexLifeName}")
    private String getMeteoindexLifeName;
    @Value("${getMeteoindexLifeValue}")
    private String getMeteoindexLifeValue;
    private SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
    private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
    private SimpleDateFormat dateFormat11 = new SimpleDateFormat("yyyyMMddHH");
    private DecimalFormat doubleFormat   = new DecimalFormat("######0.000");

    @Autowired
    private DownFileRead downFileRead = new DownFileRead();


    private long start;//sessionId建立时间

    private List<RealHost> realHostList;//物理机列表
    private List<VMHost> vmHostList;//虚拟机列表
    private String fileName = "";
    private long timestamp = 0;
    private long timestampOCF1H = 0;
    private long timestampOCF3H = 0;
    private long timestampOCF12H = 0;
    private Map<String, Object> cloud = null;//气象云
    private Map<String, Object> weather = null;

    private long yubao;//预报时间戳


    /**
     * @param time     请求数据的时间
     * @param dataCode 几小时间隔
     */
    public Map<String, Long> getNewFileJson(String time, String dataCode) {
        Map<String, Long> rtn = new HashMap<>();
        String signature = null;
        String AccessKeySecretUTF8 = null;
        String timestamp = simpleDateFormat.format(new Date());
        Map<String, String> parameter = new HashMap<>();
        parameter.put("time", time);
        parameter.put("accessKeyID", AccessKeyId);
        parameter.put("signatureMethod", "HMAC-SHA1");
        parameter.put("timestamp", timestamp);

        try {
            signature = SignatureUtils.generate("GET", parameter, AccessKeySecret);
            AccessKeySecretUTF8 = URLEncoder.encode(AccessKeyId, "UTF-8");
            signature = URLEncoder.encode(signature, "UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
        }

        String param = "time="
                + time
                + "&accessKeyID="
                + AccessKeySecretUTF8
                + "&signature=" + signature
                + "&signatureMethod=HMAC-SHA1"
                + "&timestamp=" + timestamp;
        Map<String, Object> map1 = HttpUtil.doGet(showurl + "/timestamp?" + param);
        Map map = getHttpRtnBodyToMap(map1);
        logger.info("最新数据时间戳:"+map);
        boolean resutlString = (boolean) map.get("success");
        if (resutlString) {
            Map<String, Object> result = (Map<String, Object>) map.get("result");
            if ("OCF1H".equals(dataCode)) {
                List<Long> original = (List<Long>) ((Map<String, Object>) result.get("OCF1H")).get("original");
                rtn.put("OCF1H", original.get(0));
            }

            if ("OCF3H".equals(dataCode)) {
                List<Long> original = (List<Long>) ((Map<String, Object>) result.get("OCF3H")).get("original");
                rtn.put("OCF3H", original.get(0));
            }

            if ("OCF12H".equals(dataCode)) {
                List<Long> original = (List<Long>) ((Map<String, Object>) result.get("OCF12H")).get("original");
                rtn.put("OCF12H", original.get(0));
            }

            if ("LAPS3KM".equals(dataCode)) {
                List<Long> original = (List<Long>) ((Map<String, Object>) result.get("LAPS3KM")).get("original");
                rtn.put("LAPS3KM", original.get(0));
            }
        }
        return rtn;
    }

    public Map getHttpRtnBodyToMap(Map<String, Object> map1) {
        byte[] bytes = (byte[]) map1.get("content");
        Map map = null;
        try {
            String res = new String(bytes, "UTF-8");
            return ConvertUtil.jsonStrToObject(res, Map.class);
        } catch (Exception e) {
            logger.error("解析http body出现错误", e);
            return null;
        }
    }

    public String downLastFileByJson(Map<String, String> map) {
        synchronized (TestDataRes.class) {
            String time = map.get("time");
            String dataCode = map.get("dataCode");
            String tempLocalDirectory = null;

            String format = "dat";
            String fc = "original";
            //最新时间
            long timestamp1 = getNewFileJson(time, dataCode).get(dataCode);
            String fileName = timestamp1 + "_MSP3_PMSC_" + dataCode + "_ME_L88_GLB_" + time.substring(0, time.length() - 2) + "_00000-36000.DAT";



            if ("OCF12H".equals(dataCode)) {
                tempLocalDirectory = localDirectory + "/OCF/12H/";

                if ((timestamp1 - timestampOCF12H) <= (6 * 60 * 60 * 1000) && timestampOCF12H != 0) {
                    return tempLocalDirectory + fileName;
                }
                timestampOCF12H = timestamp1;
                timestamp = timestamp1;
            }
            if ("OCF3H".equals(dataCode)) {
                tempLocalDirectory = localDirectory + "/OCF/3H/";
                if ((timestamp1 - timestampOCF3H) <= (6 * 60 * 60 * 1000) && timestampOCF3H != 0) {
                    return tempLocalDirectory + fileName;
                }
                timestampOCF3H = timestamp1;
                timestamp = timestamp1;
            }
            if ("OCF1H".equals(dataCode)) {
                tempLocalDirectory = localDirectory + "/OCF/1H/";
                if ((timestamp1 - timestampOCF1H) <= (6 * 60 * 60 * 1000) && timestampOCF1H != 0) {
                    return tempLocalDirectory + fileName;
                }
                timestampOCF1H = timestamp1;
                timestamp = timestamp1;
            }
            if ("LAPS3KM".equals(dataCode)) {
                tempLocalDirectory = localDirectory + "/LAPS/LAPS3KM/";
                format = "gr2";
            }
            //MSP3_PMSC_OCF3H_ME_L88_GLB_YYYYMMDDHHTT_00000-36000.DAT
            final String filePath = tempLocalDirectory + fileName;//拼接文件名称和地址
            File file = new File(filePath);
            if (file.exists()&&file.length()>1000){
                return filePath;
            }
            String nonce = UUID.randomUUID().toString();
            String AccessKeySecretUTF8 = null;
            String signature = "";

            //创建临时目录
            File tmpFile = new File(tempLocalDirectory);
            if (!tmpFile.exists()) {
                tmpFile.mkdirs();
            }

            Map<String, String> parameter = new HashMap<String, String>();
            try {
                parameter.put("dataCode", dataCode);
                parameter.put("elements", "ME");
                parameter.put("time", time);
                parameter.put("type", "L88");
                parameter.put("accessKeyID", AccessKeyId);
                parameter.put("format", format);
                parameter.put("version", "1.0");
                parameter.put("signatureMethod", "HMAC-SHA1");
                parameter.put("signatureNonce", nonce);
                parameter.put("timestamp", timestamp + "");
                parameter.put("fc", fc);

                signature = SignatureUtils.generate("GET", parameter, AccessKeySecret);
                //System.out.println("signature: " + signature);
                AccessKeySecretUTF8 = URLEncoder.encode(AccessKeyId, "UTF-8");
                signature = URLEncoder.encode(signature, "UTF-8");
            } catch (Exception e) {
                e.printStackTrace();
            }
            String url = showurl+"/down?dataCode=" + dataCode + "&elements=ME&time="
                    + time
                    + "&type=L88&accessKeyID="
                    + AccessKeySecretUTF8
                    + "&format=" + format + "&version=1.0"
                    + "&signature=" + signature
                    + "&signatureMethod=HMAC-SHA1&signatureNonce=" + nonce
                    + "&timestamp=" + timestamp + "&fc=" + fc;
            Map<String, Object> map1 = HttpUtil.doGet(url);

            byte[] bytes = (byte[]) map1.get("content");

            try {
                FileWriter fileWriter = new FileWriter(filePath);
                String res = new String(bytes, StandardCharsets.UTF_8);
                fileWriter.write(res);
                fileWriter.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            new Thread(() -> {
                try {
                    Thread.sleep(2 * 60 * 60 * 1000);
                    File downloadFile = new File(filePath);
                    if (downloadFile.exists()) downloadFile.delete();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }).start();
            try {
                Thread.sleep(30 * 1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return filePath;
        }
    }

    /**
     * 智慧预报左右
     *
     * @param station
     * @return list8hours 8小时预报 list4days 4天预报
     */
    @GetMapping("/get8hours")
    @ResponseBody
    public Map<String, Object> get8hours(@RequestParam("station") String station) {

        station = "57516";
        Map<String, Object> rtn = new HashMap<>();
        List<OCF1HForecastVO> list8hours = new ArrayList<>();
        List<OCF12HForecastVO> list4days = new ArrayList<>();
        List<OCF12HForecastVO> listsichou = new ArrayList<>();
        Map<String, String> map = new HashMap<>();
        Calendar calendar = Calendar.getInstance();

        int hours = calendar.get(Calendar.HOUR_OF_DAY);
        Date time1 = calendar.getTime();
        String time = dateFormat.format(calendar.getTime());
        String times = "";

        //每天预报06、08、12、20四个时次
        if (hours < 8) {
            times = time + "060000";

        } else if (hours < 12) {
            times = time + "080000";

        } else if (hours < 20) {
            times = time + "120000";

        } else {
            times = time + "200000";

        }
        map.put("time", times);
        map.put("dataCode", "OCF1H");
        String file = downLastFileByJson(map);
        //2个下载要求间隔30秒以上,现在满足,线上再看
        map.put("dataCode", "OCF12H");
        String OCF12H = downLastFileByJson(map);

//        String file = "/Users/liyunfeng/workspace1/cq-smart-weather/download/OCF/1H/1543884089555_MSP3_PMSC_OCF1H_ME_L88_GLB_201812040800_00000-36000.DAT";

        List<String> timss = new ArrayList<>();
        List<String> days = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            calendar.setTime(time1);
            calendar.set(Calendar.DAY_OF_MONTH, calendar.get(Calendar.DAY_OF_MONTH) + i);

            days.add(dateFormat.format(calendar.getTime()) + "20");
        }
        for (int i = 0; i <= 8; i++) {
            calendar.setTime(time1);
            calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY) + i);
            timss.add(dateFormat11.format(calendar.getTime()));
        }

        try {
            List<Object> list1 = downFileRead.readFileOCF1HForecastVO(file);
            List<Object> list12 = downFileRead.readFileOCF1HForecastVO(OCF12H);
            if (list1 == null || list1.size() == 0) return null;
            for (Object object : list1) {
                OCF1HForecastVO ocf1HForecastVO = (OCF1HForecastVO) object;
                if (ocf1HForecastVO.getStationID().equals(station) && timss.contains(ocf1HForecastVO.getLST_FORECAST_TIME())) {
                    list8hours.add(ocf1HForecastVO);
                }
            }
            for (Object object : list12) {
                OCF12HForecastVO ocf3HForecastVO = (OCF12HForecastVO) object;
                if (ocf3HForecastVO.getStationID().equals(station) && days.contains(ocf3HForecastVO.getLST_FORECAST_TIME())) {
                    list4days.add(ocf3HForecastVO);
                }
                if ((ocf3HForecastVO.getLST_FORECAST_TIME()).contains((time+"2"))||(ocf3HForecastVO.getLST_FORECAST_TIME()).contains((time+"19"))) {
                    listsichou.add(ocf3HForecastVO);
                }
                //listsichou.add(ocf3HForecastVO);
            }
        } catch (Exception e) {
            logger.error("获取数据失败", e);

        } finally {
            rtn.put("list8hours", list8hours);
            rtn.put("list4days", list4days);
            rtn.put("listsichou", listsichou);
            logger.info("以获取8小时数据");
        }
        return rtn;
    }

    /**
     * 空气质量
     *
     * @return
     */
    @GetMapping("/getStringAir")
    public Map<String, Object> getStringAir() {

//
        FTPListAllFiles ftpListAllFiles = new FTPListAllFiles();
        try {
            ftpListAllFiles.connectServer(FTPhost, FTPport, FTPusername, FTPpassword, FTPpath);
            Calendar calendar = Calendar.getInstance();
            int hours = calendar.get(Calendar.HOUR_OF_DAY);
            String filename = "";
            if (hours < 20) {
                calendar.add(Calendar.DAY_OF_MONTH, -1);
                filename = dateFormat.format(calendar.getTime()) + "20.TXT";
            } else filename = dateFormat.format(calendar.getTime()) + "20.TXT";

            Map<String, Object> rtn = ftpListAllFiles.readFile(filename);
            ftpListAllFiles.closeServer();
            try {
                rtn.put("airNum", getAirNum());
            } catch (Exception e) {
                e.printStackTrace();
            }
            return rtn;
        } catch (Exception e) {
            e.printStackTrace();
        }


        return null;
    }


    public String getAirNum() {
        String station = "57516";
        String timeAir = "";
        Calendar calendar = Calendar.getInstance();

        if (calendar.get(Calendar.HOUR_OF_DAY) >= 23) {//明天7点
            timeAir = dateFormat.format(calendar.getTime()) + "230000";
        } else {//今天7点
            calendar.add(Calendar.DAY_OF_MONTH, -1);
            timeAir = dateFormat.format(calendar.getTime()) + "230000";
        }

        String url = cimissUrl + "&interfaceId=getCawnEleByTimeAndStaID&dataCode=CAWN_CHN_PMM_MIN" +
                "&times=" + timeAir +
                "&staIds=" + station +
                "&elements=Station_Id_C,Station_Name,Province,Year,Mon,Day,Hour,Min,PM2p5_Densty" +
                "&limitCnt=30" +
                "&dataFormat=json";
        try {
            Map<String, Object> map1 = HttpUtil.doGet(url);
            Map httpRtnBodyToMap = getHttpRtnBodyToMap(map1);
            List<Map<String, Object>> ds = (List<Map<String, Object>>) httpRtnBodyToMap.get("DS");
            for (Map<String, Object> d : ds) {
                String pm2p5_densty = (String) d.get("PM2p5_Densty");
                return pm2p5_densty;
            }
        } catch (Exception e) {
            return null;
        }
        return null;
    }


    /**
     * c穿衣指数
     */
    @RequestMapping(value = "/getXXZX_SPMD_getMeteoindexLife")
    public Map<String, String> getXXZX_SPMD_getMeteoindexLife(@RequestParam("station") String station) {

        Map<String, String> req = new HashMap<>();
        Map<String, String> rtn = new HashMap<>();
        req.put("stationNum", station);
        req.put("username", getMeteoindexLifeName);
        req.put("password", getMeteoindexLifeValue);
        Map<String, Object> map1 = HttpUtil.doPost(getMeteoindexLife+"/SPMDService/MeteoInfoService/XXZX_SPMD_getMeteoindexLifeLatest", req);
        byte[] bytes = (byte[]) map1.get("content");
        try {
            String res = new String(bytes, "UTF-8");
            //System.out.println (res);
            GsonJsonParser gsonJsonParser = new GsonJsonParser();
            List<Object> objects = gsonJsonParser.parseList(res);
            for (Object object : objects) {
                rtn = (Map<String, String>) object;
            }
        } catch (Exception e) {
            logger.error("解析http body出现错误", e);
        }
        return rtn;
    }
    @GetMapping("/getDateSource")
    public List<Map<String,Object>> getDateSource() throws ParseException {
        List<Map<String,Object>> list = new ArrayList<>();
        String url = ffAdress+"/web/rbac/user/login";
            Map<String,Object> rtn ;
            Map<String ,Object> map = new HashMap<>();
            map.put("user_email",user_email);
            map.put("user_password",user_password);
            Map<String, Object> map1 = HttpUtil.doPost(url, map);

            Header[] responseHeader = (Header[]) map1.get("responseHeader");
            if (responseHeader==null){
            logger.error("登录飞鱼平台失败");
            return list;
        }
        String session = "";
        for (Header header : responseHeader) {
            if ("Set-Cookie".equals(header.getName())){
                session=header.getValue();
            }
        }
        Map<String ,Object> map2 = new HashMap<>();
        map2.put("id",shujuziyuan);
        map2.put("vars","{}");
        Map<String ,Object> hearderMap = new HashMap<>();
        hearderMap.put("Cookie",session);

        Map<String, Object> map3 = HttpUtil.doPost(ffAdress+"/web/visualScreen/screenEditor/getModelData", hearderMap, map2);
        Map<String,Object> httpRtnBodyToMap = getHttpRtnBodyToMap(map3);
        if ((int)httpRtnBodyToMap.get("code")==0){
           Map<String, Object> data = (Map<String, Object>) httpRtnBodyToMap.get("data");
           Calendar calendar =Calendar.getInstance();
           long time1 = calendar.getTime().getTime();
           List<Map<String, Object>>  data1 = (List<Map<String, Object>>) data.get("data");
            for (Map<String, Object> stringObjectMap : data1) {
                String dailyIncrement = (String) stringObjectMap.get("DailyIncrement");
                String Type = (String) stringObjectMap.get("Type");
                String Total = (String) stringObjectMap.get("Total");
                String BeginTime = (String) stringObjectMap.get("BeginTime");

                if (StringUtils.isEmpty(dailyIncrement)||StringUtils.isEmpty(Type)||StringUtils.isEmpty(Total)||StringUtils.isEmpty(BeginTime))continue;
                Date parse = dateFormat.parse(BeginTime);
                long time = parse.getTime();
                long l = time1 - time;
                int count = (int) (l/(60*60*24*1000));
                double value =(Double.valueOf(dailyIncrement) * count)+ Integer.valueOf(Total) ;
                rtn = new HashMap<>();
                rtn.put("Type",Type);
                rtn.put("Total",doubleFormat.format(value));
                list.add(rtn);
            }
        }
        return list;
    }

    public static void main(String[] args) {
        TestDataRes testDataRes = new TestDataRes();
        try {
            List<Map<String, Object>> dateSource = testDataRes.getDateSource();
            for (Map<String, Object> map : dateSource) {
                System.out.println(map);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
